#include "gd32w51x.h"
#include "stdio.h"
#include "stdint.h"
#include "DevicesSoftTimer.h"
#include "DevicesTime.h"
#include "DevicesBeep.h"


BeepInfoType g_typeBeepInfo = {BEEP_DISABLE, 0, BEEP_OPEN_DEF_TIME, BEEP_CLOSE_DEF_TIME};
SoftTimerTypeDef g_typeSoftTimerBeepHanle = {0};
SoftTimerTypeDef g_typeSoftTimerTimeShowHanle = {0};


void vSoftTimerBeepCallbackFunction(void *pvHandle)
{
    (void)pvHandle;

    vBeepMachine();
}

void vSoftTimerTimeShowCallbackFunction(void *pvHandle)
{
    (void)pvHandle;

    printf("CST: %s %s\r\n", pcStampToDateStrings(lTimeGetStamp() / 1000000), pcStampToTimeStrings(lTimeGetStamp() / 1000000));
}


void vBeepInit(void)
{
    /* enable the LED2 GPIO clock */
    rcu_periph_clock_enable(RCU_GPIOC);

    /* configure LED GPIO pin */
    gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_14);
    gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_14);

    gpio_bit_reset(GPIOC, GPIO_PIN_14);

    BEEP_CLOSE();

    /* 软件定时器周期调用 */
    cSoftTimerCreateMs(&g_typeSoftTimerBeepHanle, 100, softTimerOpen | softTimerCircular, vSoftTimerBeepCallbackFunction);
    cSoftTimerCreateMs(&g_typeSoftTimerTimeShowHanle, 1000, softTimerOpen | softTimerCircular, vSoftTimerTimeShowCallbackFunction);
}

int8_t cBeepSetState(BeepStateEnum enumState, int8_t cCnt)
{
    g_typeBeepInfo.state = enumState;
    g_typeBeepInfo.cntSet = cCnt;

    return 0;
}

void vBeepStateMachine(BeepInfoType *ptypeBeep)
{
    switch(ptypeBeep->state)
    {
        case BEEP_DISABLE:
            BEEP_CLOSE();
            break;

        case BEEP_NORMAL:
            /* 系统每100ms调用一次本函数 */
            ptypeBeep->timeNow += (ptypeBeep->cntSet > 0) ? 100 : 0;
            ptypeBeep->cntSet -= (ptypeBeep->timeNow >= (ptypeBeep->timeOpen + ptypeBeep->timeClose)) ? 1 : 0;
            ptypeBeep->timeNow %= (ptypeBeep->timeOpen + ptypeBeep->timeClose);

            (ptypeBeep->timeNow < ptypeBeep->timeOpen) ? BEEP_OPEN() : BEEP_CLOSE();
            break;

        case BEEP_CIRCULAR:
            ++ptypeBeep->timeNow;
            ptypeBeep->timeNow %= (ptypeBeep->timeOpen + ptypeBeep->timeClose);

            (ptypeBeep->timeNow < ptypeBeep->timeOpen) ? BEEP_OPEN() : BEEP_CLOSE();
            break;

        default: break;
    }
}

void vBeepMachine(void)
{
    vBeepStateMachine(&g_typeBeepInfo);
}

BeepInfoType *ptypeBeepGetInfo(void)
{
    return &g_typeBeepInfo;
}
